using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
using System.Threading;

namespace CSharpDuino
{
    public delegate void KeyButtonEvent(char c);

    public class NumericKeyboard
    {
        public event KeyButtonEvent KeyPress;
        public event KeyButtonEvent KeyDown;

        private char[][] keys = new char[][]
        {
            new char[] {'1','2','3'},
            new char[] {'4','5','6'},
            new char[] {'7','8','9'},
            new char[] {'*','0','#'}
        };

        private bool[][] state = new bool[][]
        {
            new bool[] {false,false,false},
            new bool[] {false,false,false},
            new bool[] {false,false,false},
            new bool[] {false,false,false}
        };

        private readonly OutputPort[] columns = new OutputPort[3];
        
        private readonly InputPort[] rows = new InputPort[4];
        
        public NumericKeyboard()
        {
            this.columns[0] = new OutputPort(Pins.GPIO_PIN_D4, false);
            this.columns[1] = new OutputPort(Pins.GPIO_PIN_D6, true);
            this.columns[2] = new OutputPort(Pins.GPIO_PIN_D2, true);

            this.rows[0] = new InputPort(Pins.GPIO_PIN_D5, false, ResistorModes.Disabled);
            this.rows[1] = new InputPort(Pins.GPIO_PIN_D0, false, ResistorModes.Disabled);
            this.rows[2] = new InputPort(Pins.GPIO_PIN_D1, false, ResistorModes.Disabled);
            this.rows[3] = new InputPort(Pins.GPIO_PIN_D3, false, ResistorModes.Disabled);
        }

        public void Read()
        {
            for (int c = 0; c < this.columns.Length; c++)
            {
                for (int o = 0; o < this.columns.Length; o++)
                {
                    this.columns[o].Write(c != o);
                    //Debug.Print(o.ToString() + " / " + (c != o).ToString());
                }

                //Thread.Sleep(100);

                for (int r = 0; r < this.rows.Length; r++)
                {
                    var newState = !rows[r].Read();
                    if (newState)
                    {
                        //Debug.Print("C: "+c.ToString() + " x R: " + r.ToString() + " = " + keys[r][c].ToString());
                    }

                    if (state[r][c] != newState)
                    {
                        //Debug.Print(keys[r][c].ToString());
                    }

                    if (state[r][c] != newState && !newState)
                    {
                        // Debug.Print(keys[r][c].ToString());
                        if (this.KeyPress != null)
                        {
                            this.KeyPress(keys[r][c]);
                        }
                    }

                    if (state[r][c] != newState && newState)
                    {
                        if (this.KeyDown != null)
                        {
                            this.KeyDown(keys[r][c]);
                        }
                    }

                    state[r][c] = newState;

                    //  Thread.Sleep(100);
                }

                //Thread.Sleep(30);
            }
          //  Debug.Print("=========================");
        }

    }
}
